<?php
declare (strict_types=1);

namespace app\admin\controller;

use app\api\exception\HttpExceptionHandle;
use app\common\auth\JwtAuth;
use app\common\controller\Api;
use app\common\lib\HttpError;
use Redis;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Db;
use think\Request;


/**
 * @note    登陆
 * @author  liujian
 * Class Login
 * @package app\admin\controller
 * @Create  Date : 2021年04月01日 下午1:57:18
 */
class Login extends Api
{
    /**
     * @OA\Post(path="/login/login",
     *   tags={"登录管理"},
     *   summary="登录",
     *   @OA\Parameter(name="token", in="header", description="token", @OA\Schema(type="string", default="123456")),
     *     @OA\RequestBody(
     *     @OA\MediaType(
     *       mediaType="multipart/form-data",
     *         @OA\Schema(
     *           @OA\Property(description="账号", property="username", type="string", default="admin"),
     *           @OA\Property(description="密码", property="password", type="int", default="123456"),
     *           required={"username", "password"})
     *       )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="The Member",
     *         @OA\JsonContent(type="object",
     *             @OA\Property(property="msg", type="string"),
     *             @OA\Property(property="code", type="integer", default="200"),
     *             @OA\Property(property="data", type="object",
     *                  @OA\Property(property="info", type="object",description="用户详情"),
     *                  @OA\Property(property="token", type="string",description="Token"),
     *                  @OA\Property(property="power_list", type="object",description="权限列表"),
     *             ),
     *         ),
     *      ),
     * )
     */
    public function login(string $username, string $password)
    {
        $redis = new Redis();
        $redis->connect(Config::get('cache.stores.redis.host'), 6379);
        $redis->auth(Config::get('cache.stores.redis.password'));
        $redis->select((int)Config::get('cache.stores.redis.select'));//这个key记录该ip的访问次数 也可改成用户id
        $key = get_real_ip();//该Key记录访问的次数，目前是以IP为例，也可以把用户id作为key，如userid_123456
        //限制次数。
        $limit = 1;
        $check = $redis->exists($key);
        if ($check) {
            $redis->incr($key);
            $count = $redis->get($key);
            if ($count > $limit)
                throw new ValidateException('请求超频');

        } else {
            $redis->incr($key);
            //限制时间为60秒
            $redis->expire($key, 1);
        }
        $info = Db::name('admin')->where('name', $username)->find();
        if (empty($info))
            throw new ValidateException('账号或密码错误');
        if ($info['status'] == 2)
            throw new ValidateException('该管理员账号已被冻结');
        if ($info['pwd'] != md5($password))
            throw new ValidateException('账号或密码错误');

        $jwtauth = JwtAuth::getInstance();
        $token = $jwtauth->makeToken((int)$info['id'], (string)$info['pwd'])->getToken();

        // redis记录缓存
        saveRedisAdmin($token, $info);


        $admin_id = $info['id'];
        if ($admin_id != 1 && $admin_id != 2 && $admin_id != 3) {
            // 获取用户权限
            // 获取角色
            $role_ids = Db::name("admin_role")->where("admin_id", $info['id'])->column("role_id");
            // 获取权限
            $power_ids = Db::name("role_power")->where("role_id", "in", $role_ids)->column("power_id");
            $power_list = Db::name("power")->where("id", "in", $power_ids)->where('status', 1)->order('sort', 'desc')->select()->toArray();
        } else {
            $power_list = Db::name("power")->where('status', 1)->order('sort', 'desc')->select()->toArray();
        }
        $power_list = recursion($power_list);
        return $this->jsonSuccessData("登录成功", [
            "info"       => $info,
            "power_list" => $power_list,
            "token"      => $token
        ]);
    }

    /**
     * @OA\Get(path="/login/loginOut",
     *   tags={"登录管理"},
     *   summary="退出登录",
     *   @OA\Parameter(name="token", in="header", description="token", @OA\Schema(type="string", default="123456")),
     *   @OA\Response(
     *       response=200,
     *       description="The Member",
     *       @OA\JsonContent(type="object",
     *           @OA\Property(property="msg", type="string"),
     *           @OA\Property(property="code", type="integer", default="200"),
     *           @OA\Property(property="data", type="object",
     *           ),
     *       ),
     *    ),
     * )
     */
    public function loginOut()
    {
        $token = trim(Request::header('token'));//实例化
        $jwtauth = JwtAuth::getInstance();// 放入token
        $jwtauth->setToken($token);// 实例化值
        try {
            $jwtauth->parserToken();
        } catch (\Exception $e) {
            throw new HttpExceptionHandle(HttpError::TOKEN_ERR_ADMIN);
        }
        // 获得admin_id
        $admin_id = $jwtauth->getUuid();// 这一步清理之前该用户储存的redis
        Cache::store('redis')->delete((string)Cache::store('redis')->get("admin_user_" . $admin_id));
        return $this->jsonSuccessData("操作成功");

    }
}
